package br.com.guiav6.sisguia.repository.hibernate;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import javax.persistence.TypedQuery;

import br.com.guiav6.sisguia.repository.Dao;
import br.com.guiav6.sisguia.utils.ReflectionUtil;

public abstract class AbstractDaoHibernate<K, E> implements Dao<K, E> {
    
	@PersistenceContext(unitName="sisguia",name="sisguia", type = PersistenceContextType.EXTENDED)
    private EntityManager entityManager;
    
    protected Class<E> entityClass;
    
    @SuppressWarnings("unchecked")
    public AbstractDaoHibernate() {
        ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
        this.entityClass = (Class<E>) genericSuperclass.getActualTypeArguments()[1];
    }
    
    @Override
    public List<E> findAll() {
        TypedQuery<E> tq = entityManager.createQuery("select e from " + entityClass.getSimpleName() + " as e", entityClass);
        return tq.getResultList();
    }
    
    @Override
    public E findById(K id) {
        return entityManager.find(entityClass, id);
    }
    
    @Override
    public E merge(E entity) {
        entity = entityManager.merge(entity);
        return entity;
    }
    
    @Override
    public void persist(E entity) {
        entityManager.persist(entity);
    }
    
    @Override
    public void refresh(E entity) {
        entityManager.refresh(entity);
    }
    
    @Override
    public void addAll(List<E> entities) {
        for (E e : entities) {
            entityManager.persist(e);
        }
        
    }
    
    protected EntityManager getEntityManager() {
        return entityManager;
    }
    
    @Override
    public void removeAllEntities(List<E> entities) {
        if (entities != null) {
            for (E e : entities) {
                E entity;
                try {
                    entity = getEntityManager().find(entityClass, Long.valueOf(ReflectionUtil.invocarMetodoGet(e, "id").toString()));
                    getEntityManager().remove(entity);
                } catch (NumberFormatException e1) {
                } catch (SecurityException e1) {
                } catch (IllegalArgumentException e1) {
                } catch (NoSuchMethodException e1) {
                } catch (IllegalAccessException e1) {
                } catch (InvocationTargetException e1) {
                }
            }
        }
    }
    
}
